/**
 * Copyright (C) 2013-2014 the original author or authors.
 */
package com.foreveross.bsl.openfire;

import java.util.Date;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.foreveross.bsl.JsonMapper;
import com.foreveross.bsl.PushMessage;

/**
 * xxx
 *
 * @author Wangyi
 * @version v1.0
 *
 * @date 2013-12-5
 *
 */
public class OpenfireClient implements ChatManagerListener{
	
	private static final Logger log = LoggerFactory.getLogger(OpenfireClient.class);
	public static final String PREFIX_USERNAME="newuser";
	public static final String PREFIX_PWD="password";
	
	private final String host;
	private final int port;
	private String username;
	private String password;
	protected Connection conn;
	private ReceiveStatisticMessageListener receiveStatMessageListener;
	
	public OpenfireClient(String host, int port) {
		this.host=host;
		this.port=port;
		this.conn=buildConnection();
		this.conn.getChatManager().addChatListener(this);
	}
	
	private Connection buildConnection() {
		ConnectionConfiguration config = new ConnectionConfiguration(host, port);
		config.setCompressionEnabled(true);
		config.setSecurityMode(SecurityMode.enabled);
		config.setSASLAuthenticationEnabled(true);
		return new XMPPConnection(config);
	}
	
	public static void main(String[] args) throws Exception{
		OpenfireClient oc = new OpenfireClient("10.108.1.216", 5222);
		oc.setUsername("push");
		oc.setPassword("111111");
		oc.login();
		System.out.println("login ok!");
		Thread.sleep(10000);
	}
	
	public void connect() throws XMPPException{
		if (!conn.isConnected()){
			try {
				conn.connect();
			} catch (XMPPException e) {
				log.error("connect error! host:{}, port:{}",host, port);
				throw e;
			}
		}
	}

	public void login() throws XMPPException {
		connect();
		try {
			conn.login(username, password, "push-test");
		} catch (XMPPException e) {
			log.error("login error! username:{}, password:{}",username, password);
			throw e;
		}
	}
	
	private int msgId=0;
	private final static MessageListener DUMMY_MSG_LISTENER=new MessageListener(){
		@Override
		public void processMessage(Chat chat, Message message) {
		}
	};
	
	public void sendMessage(String targetJid, String title, MessageListener msgListener) throws Exception {
		PushMessage pMsg=new PushMessage();
		pMsg.setId(++msgId+"");
		pMsg.setSendTime(new Date());
		pMsg.setTitle(title);
		Message msg=new Message();
		msg.setBody(JsonMapper.NON_EMPTY_JSON_MAPPER.toJson(pMsg));
		this.conn.getChatManager().createChat(targetJid, msgListener).sendMessage(msg);
	}
	
	public void sendMessage(String targetJid, String title) throws Exception {
		this.sendMessage(targetJid, title, DUMMY_MSG_LISTENER);
	}
	
	public Connection getConnection(){
		return this.conn;
	}
	
	@Override
	public void chatCreated(Chat chat, boolean createdLocally) {
		if(!createdLocally && this.receiveStatMessageListener!=null){
			chat.addMessageListener(this.receiveStatMessageListener);
		}
	}
	
	public void setReceiveStatisticMessageListener(ReceiveStatisticMessageListener receiveStatMessageListener){
		this.receiveStatMessageListener=receiveStatMessageListener;
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param username the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}
	
}
